package edu.whu.demo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import edu.whu.demo.dao.ActivityDao;
import edu.whu.demo.dao.UserDao;
import edu.whu.demo.domain.Comment;
import edu.whu.demo.dao.CommentDao;
import edu.whu.demo.domain.CommentDTO;
import edu.whu.demo.domain.Message;
import edu.whu.demo.exception.CommentException;
import edu.whu.demo.exception.MessageException;
import edu.whu.demo.service.ICommentService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 
 * @since 2022-11-24
 */
@Service
public class CommentServiceImpl extends ServiceImpl<CommentDao, Comment> implements ICommentService {

    // 表示是活动下的一级评论
    public static final String DYNAMIC="dynamic";

    // 表示是一级评论下的二级评论
    public static final String COMMENT="comment";

    @Autowired
    CommentDao commentDao;

    @Autowired
    UserDao userDao;

    @Autowired
    ActivityDao activityDao;

    @Autowired
    MessageServiceImpl messageService;

    @Override
    public Comment addComment(Comment comment) throws CommentException, MessageException {
        // 插入数据库之前需要对插入数据进行外键约束检查
        // comment.getFromUid() == null会让userDao.findUserByUid(comment.getFromUid())报错
        // 检查from_uid是否对应一个用户
        if (userDao.selectById(comment.getFromUid())==null)
        {
            throw new CommentException("发送评论的用户账号不存在！");
        }
        // 如果是一级评论，需要检查其parent_id是否对应一个活动
        if (DYNAMIC.equals(comment.getType())
                && activityDao.selectById(comment.getParentId()) == null)
        {
            throw new CommentException("评论的活动不存在！");
        }
        // 如果是二级评论
        if (COMMENT.equals(comment.getType()))
        {
            // 需要检查其parent_id是否对应一个一级评论
            Comment parentComment = this.baseMapper.selectById(comment.getParentId());
            if (parentComment == null || !DYNAMIC.equals(parentComment.getType()))
            {
                throw new CommentException("回复的活动不存在！");
            }
            // 需要检查其to_uid是否对应一个用户
            if (userDao.selectById(comment.getToUid())==null)
            {
                throw new CommentException("回复的用户不存在！");
            }
            Message message = new Message();
            message.setType("comment");
            message.setToUid(comment.getToUid());
            message.setFromUid(comment.getFromUid());
            message.setActivityId(parentComment.getParentId());
            message.setTime(LocalDateTime.now());
            message.setContent(comment.getContent());
            message.setIsRead(0);
            messageService.addMessage(message);
        }
        this.baseMapper.insert(comment);

        return comment;

    }

    @Override
    public void deleteComment(Long id) throws CommentException {
        Comment comment = findComment(id);
        // 如果该评论是一级评论，需要先删除其下所有二级评论
        if (DYNAMIC.equals(comment.getType()))
        {
            List<CommentDTO> secondComments = this.baseMapper.findSecondCommentsByParentId(id);
            for (CommentDTO secondComment: secondComments)
            {
                this.baseMapper.deleteById(secondComment.getId());
            }
        }
        this.baseMapper.deleteById(id);

    }

    @Override
    public void updateComment(Long id, Comment comment) throws CommentException {
        if(comment.getId()!=id){
            throw new CommentException("评论与id不符！");
        }
        else this.baseMapper.updateById(comment);
    }

    @Override
    public Comment findComment(Long id) throws CommentException {
        Comment comment = this.baseMapper.selectById(id);
        // 异常处理
        if(comment==null){
            throw new CommentException("评论不存在！");
        }
        return comment;
    }

    @Override
    public IPage<Comment> findDetailComments(Long id, Integer pageNum, Integer pageSize) {
        // 按照时间升序排列
        Page<Comment> page = new Page<Comment>(pageNum, pageSize)
                .addOrder(OrderItem.asc("time"));
        QueryWrapper<Comment> qw = new QueryWrapper<>();
        qw.eq("id", id)
                .or(i->i.eq("type",COMMENT).eq("parent_id", id));
        this.baseMapper.selectPage(page, qw);
        return page;
    }



    public  List<CommentDTO> findComment2(Long id) {
        //先一级评论
        List<CommentDTO> result = commentDao.findFirstCommentsByParentId(id);

        List<CommentDTO> temp = new ArrayList<>();

        //根据每个一级评论的id，获得其对应的二级评论
        for (Comment comment: result) {
                //添加comment到temp
            temp.addAll(commentDao.findSecondCommentsByParentId(comment.getId()));
        }
        result.addAll(temp);

        return result;
        //如果理解错误，应该换成to_uid
    }

    @Override
    public void likeComment(Long id) {
        commentDao.likeComments(id);
    }

    @Override
    public void disLikeComment(Long id) {
        commentDao.disLikeComments(id);
    }

    @Override
    public IPage<CommentDTO> searchComment(Map<String, Object> condition, Integer pageNum, Integer pageSize) {
        Page<CommentDTO> page = new Page<>(pageNum,pageSize);
        QueryWrapper<CommentDTO> qw = new QueryWrapper<>();
        System.out.println(condition);

        qw.eq("need_check",true);

        qw.like(condition.containsKey("keyword"),"p.content",condition.get("keyword"));

        //默认升序
        if(!condition.containsKey("order"))
            qw.orderByDesc("p.time");
        else qw.orderBy(condition.containsKey("order"), (Boolean) condition.get("order"),"p.time");

        commentDao.searchComment(page,qw);
        return page;
    }

    public List<Comment> getAll(){
        return commentDao.getAll();
    }
}
